import express, { Express, Request, Response, NextFunction } from 'express';
import session from 'express-session';
import { authConfig } from './config';
import { appConfig } from './config';
import { globalAuthMiddleware } from './middleware/auth';
import routes from './routes';
import appRoutes from './routes/appRoutes';
import path from 'path';
import logger from './utils/logger';
import bodyParser from 'body-parser';

declare module 'express-session' {
    interface SessionData {
        user?: any;
        captcha?: string;
        uuid?: string;
    }
}

const app: Express = express();

// 1. 首先配置 body 解析中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 2. 配置session中间件
app.use(session({
    secret: authConfig.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'lax',  // 允许跨站点请求
        maxAge: 24 * 60 * 60 * 1000 // 24小时
    }
}));

// 3. 添加 CORS 中间件
app.use((req: Request, res: Response, next: NextFunction) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

    if (req.method === 'OPTIONS') {
        return res.sendStatus(200);
    }
    next();
});

// 4. 请求日志中间件
app.use((req: Request, res: Response, next: NextFunction) => {
    // 跳过静态资源请求的详细日志
    if (req.originalUrl.match(/\.(js|html|png|jpg|css|ico|svg|woff|woff2|ttf|map)$/)) {
        logger.info(`Static Resource Request: ${req.originalUrl}`);
        next();
        return;
    }
    
    // 跳过微信支付回调的请求体日志，避免读取流数据
    if (req.originalUrl === '/app/payment/notify') {
        logger.info(`微信支付回调请求: ${req.originalUrl} [Method: ${req.method}]`);
        logger.info(`微信支付回调请求参数: ${JSON.stringify(req.query)}`);
        next();
        return;
    }
    
    // 其他请求的常规日志
    logger.info(`Request URL: ${req.originalUrl}`);
    logger.info(`Request Method: ${req.method}`);
    logger.info(`Query Parameters: ${JSON.stringify(req.query)}`);
    logger.info(`Route Parameters: ${JSON.stringify(req.params)}`);
    
    // 安全地记录请求体，避免尝试序列化流或大型对象
    if (req.body) {
        try {
            // 检查请求体类型，避免记录流或大型二进制数据
            const bodyType = typeof req.body;
            if (bodyType === 'object' && !Buffer.isBuffer(req.body)) {
                const bodyStr = JSON.stringify(req.body);
                // 限制日志长度，避免日志过大
                logger.info(`Body: ${bodyStr.length > 1000 ? bodyStr.substring(0, 1000) + '...(截断)' : bodyStr}`);
            } else {
                logger.info(`Body: [${bodyType} 类型数据，长度: ${Buffer.isBuffer(req.body) ? req.body.length : '未知'}]`);
            }
        } catch (error: any) {
            logger.warn(`无法记录请求体: ${error.message}`);
        }
    } else {
        logger.info('Body: No body');
    }
    
    next();
});

// 5. 静态资源中间件
// 使用相对路径指向项目根目录下的 public 文件夹
app.use('/html', express.static(path.join(__dirname, appConfig.htmlPath)));
app.use('/uploads', express.static(path.join(__dirname, appConfig.uploadPath)));

// 添加根路径访问，方便调试静态资源
app.get('/', (req: Request, res: Response) => {
    res.send('API服务运行中，静态资源请访问 /uploads 或 /html 路径');
});

// 6. 认证中间件
app.use(globalAuthMiddleware);

// 7. 路由中间件
app.use('/api', routes);
app.use('/app', appRoutes);

// 8. 错误处理中间件
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
    logger.error('Unhandled error:', err);
    res.status(500).json({
        success: false,
        message: 'Internal Server Error',
        error: err.message || 'An unexpected error occurred'
    });
});

export default app;